// 源码网址：https://raw.gitcode.com/Xuan_er123/proxy.pac/raw/main/proxy2.pac

// 初始化全局缓存
var globalDomesticRules = null;
var lastLoadTime = 0;
var RULES_URL = "https://raw.gitcode.com/Xuan_er123/proxy.pac/raw/main/direct_domian_boole.json";

function FindProxyForURL(url, host) {
    // ================== 一、匹配 ==================
    // 1.IP地址规则：IPv4地址段（内网+国内公网IP段）
    var ipv4Domestic = [
        "223.5.5.5/32",
        "223.6.6.6/32",
        "119.29.29.29/32",
        "1.12.12.12/32",
        "120.53.53.53/32",
        "180.76.76.76/32",
        "114.114.114.114/32",
        "114.114.115.115/32",
        "180.184.1.1/32",
        "180.184.2.2/32",
        "101.226.4.6/32",
        "218.30.118.6/32",
        "123.125.81.6/32",
        "140.207.198.6/32",
        "10.0.0.0/8",
        "172.16.0.0/12",
        "192.168.0.0/16",
        "127.0.0.0/8",
    ];
    
    // 2.IP地址规则：IPv6地址段（内网+国内公网IP段）
    var ipv6Domestic = [
        "2402:4e00::/128",
        "2402:4e00:1::/128",
        "2400:3200::1/128",
        "2400:3200:baba::1/128",
        "2400:da00::6666/128",
        "fc00::/7",  // 唯一本地地址
        "fe80::/10", // 链路本地地址
        "::1/128", //内网回环
        "240e::/12", //中国电信地址段
        "2408::/12", //中国联通地址段
        "2409::/12", //中国移动地址段
        "240a:4000::/21", //中国广电地址段
        "2001:da8::/32", // 中国教育网地址段
        "2402:4e00::/24", //腾讯地址段
        "2400:3200::/24", //阿里云地址段
        "240c::/32" //下一代互联网中心地址段
    ];
    
    // 3. 代理域名规则（Proxy）
    var forcedProxyDomains = {
        "youtube.com": true,
        "google.com": true,
    };

    // 4.直连域名规则（Direct）
    var domesticRules = loadDomesticRules(RULES_URL); // 从远程URL加载直连域名规则

    // ================== 二、匹配规则 ==================
    // 1. IP地址规则匹配
    var ip = dnsResolve(host);
    if (ip) {
        // IPv4匹配
        if (ip.indexOf('.') !== -1) {
            for (var i = 0; i < ipv4Domestic.length; i++) {
                var net = ipv4Domestic[i].split('/');
                if (isInNet(ip, net[0], genMask(net[1]))) {
                    return "DIRECT";
                }
            }
        }
        // IPv6匹配
        else if (ip.indexOf(':') !== -1) {
            for (var j = 0; j < ipv6Domestic.length; j++) {
                var cidr = ipv6Domestic[j];
                if (isInNet6(ip, cidr)) {
                    return "DIRECT";
                }
            }
        }
    }

    // 2.代理域名规则匹配
    if (isInForcedProxy(host, forcedProxyDomains)) {
        return "PROXY 192.168.3.15:10081; SOCKS 192.168.3.15:10080";
    }
    
    // 3.检查国内域名（从远程URL）
    if (domesticRules && isDomesticDomain(host, domesticRules)) {
        return "DIRECT";
    }
    
    // 4. 其它域名默认使用代理
    return "PROXY 192.168.3.15:10081; SOCKS 192.168.3.15:10080";
    
    // ================== 二、工具函数 ==================
    // 强制代理域名检查
    function isInForcedProxy(host, domains) {
        var parts = host.split('.');
        for (var i = 0; i < parts.length; i++) {
            var domain = parts.slice(i).join('.');
            if (domains[domain]) return true;
        }
        return false;
    }
    
    // 国内域名检查
    function isDomesticDomain(host, rules) {
        // 直接匹配完整域名
        if (rules[host]) return true;
        
        // 匹配子域名
        var parts = host.split('.');
        for (var i = 0; i < parts.length; i++) {
            var domain = '.' + parts.slice(i).join('.');
            if (rules[domain]) return true;
        }
        return false;
    }
    
    // 加载国内域名规则（带缓存和重试）
    function loadDomesticRules(url) {
        try {
            // 使用缓存（1小时内有效）
            var now = new Date().getTime();
            if (globalDomesticRules && (now - lastLoadTime < 3600000)) {
                return globalDomesticRules;
            }
            
            // 异步加载（实际PAC需要同步，这里用技巧）
            var xhr = new XMLHttpRequest();
            xhr.open('GET', url + '?t=' + now, false); // 同步请求+时间戳防缓存
            xhr.setRequestHeader('Cache-Control', 'no-cache');
            xhr.timeout = 3000; // 3秒超时
            xhr.send();
            
            if (xhr.status === 200) {
                var data = JSON.parse(xhr.responseText);
                globalDomesticRules = data.domestic || data; // 兼容不同结构
                lastLoadTime = now;
                return globalDomesticRules;
            }
        } catch(e) {
            console.log('规则加载失败: ' + e.message);
        }
        
        // 失败时返回上次成功加载的规则
        return globalDomesticRules;
    }

    // 生成IPv4掩码
    function genMask(prefix) {
        prefix = parseInt(prefix, 10);
        var mask = 0xFFFFFFFF << (32 - prefix);
        return [(mask >>> 24) & 0xFF, (mask >>> 16) & 0xFF, (mask >>> 8) & 0xFF, mask & 0xFF].join('.');
    }
    
    // IPv6 CIDR匹配
    function isInNet6(ip, cidr) {
        try {
            var [net, prefix] = cidr.split('/');
            prefix = parseInt(prefix || "128", 10);
            
            // 标准化IPv6地址
            ip = expandIPv6(ip);
            net = expandIPv6(net);
            
            // 比较前prefix位
            var ipParts = ip.split(':').flatMap(part => 
                [parseInt(part.substring(0, 2), 16), parseInt(part.substring(2), 16)]
            );
            
            var netParts = net.split(':').flatMap(part => 
                [parseInt(part.substring(0, 2), 16), parseInt(part.substring(2), 16)]
            );
            
            for (var i = 0; i < Math.floor(prefix/8); i++) {
                if (ipParts[i] !== netParts[i]) return false;
            }
            
            if (prefix % 8 !== 0) {
                var mask = 0xFF << (8 - (prefix % 8));
                var idx = Math.floor(prefix/8);
                return (ipParts[idx] & mask) === (netParts[idx] & mask);
            }
            
            return true;
        } catch(e) {
            return false;
        }
    }
    
    // 扩展缩写IPv6地址
    function expandIPv6(ip) {
        if (ip.indexOf('::') !== -1) {
            var parts = ip.split('::');
            var left = parts[0] ? parts[0].split(':') : [];
            var right = parts[1] ? parts[1].split(':') : [];
            var zeros = 8 - (left.length + right.length);
            var expanded = left.concat(Array(zeros).fill('0000')).concat(right);
            return expanded.map(part => part.padStart(4, '0')).join(':');
        }
        return ip.split(':').map(part => part.padStart(4, '0')).join(':');
    }
}

// ==== 兼容性处理 ====
if (typeof console === "undefined") {
    this.console = { 
        log: function() {},
        error: function() {} 
    };
}